package work.mediway.mdm.controller.hierarchy;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.github.xiaoymin.knife4j.annotations.DynamicParameter;
import com.github.xiaoymin.knife4j.annotations.DynamicResponseParameters;
import com.mediway.hos.base.model.BaseResponse;
import com.mediway.hos.common.config.DmpBaseConfig;
import com.mediway.hos.common.utils.file.FileUploadUtils;
import com.mediway.hos.common.utils.file.FileUtils;
import com.mediway.hos.log.annotation.OperLog;

import org.apache.commons.lang3.StringUtils;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;

import cn.hutool.core.codec.Base64Decoder;
import cn.hutool.core.codec.Base64Encoder;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import work.mediway.mdm.core.annotation.OpsLog;
import work.mediway.mdm.core.enums.OpsLogTypeEnum;
import work.mediway.mdm.core.exception.DataException;
import work.mediway.mdm.core.page.QueryRequest;
import work.mediway.mdm.core.transport.ErrorMsgVO;
import work.mediway.mdm.biz.entity.hierarchy.HosPerson;
import work.mediway.mdm.biz.service.hierarchy.HosPersonService;

@Slf4j
@Api(tags = "组织架构-人员管理")
@ApiSupport(order = 20)
@RequestMapping("/person")
@RestController
@Validated
@RequiredArgsConstructor
public class HosPersonController {

    private final HosPersonService hosPersonService;

    @ApiOperation(value = "新增人员")
    @ApiOperationSupport(order = 67)
    @OpsLog(value = "新增人员", type = OpsLogTypeEnum.INSERT)
    @OperLog(title = "新增人员", content = "新增人员")
    @PostMapping
    public BaseResponse<HosPerson> save(@Valid HosPerson hosPersonVO) {
        setPhoto(hosPersonVO);
        this.hosPersonService.saveHosPerson(hosPersonVO);
        return BaseResponse.success();
    }

    /**
     * 如果图片路径不为空，则获取图片并设置值
     *
     * @param hosPerson HosPerson
     */
    public void setPhoto(HosPerson hosPerson) {
        String imgUrl = hosPerson.getImgUrl();
        if (StringUtils.isNotBlank(imgUrl)) {
            String path = StringUtils.replace(imgUrl, "/profile", DmpBaseConfig.getProfile());
            File file = FileUtil.file(path);
            String encode = Base64Encoder.encode(FileUtil.readBytes(file));
            hosPerson.setPaPhoto(encode);
            //删除本地图片
            FileUtil.del(file);
        }
    }

    @ApiOperation(value = "查询人员")
    @ApiOperationSupport(order = 67)
    @OpsLog(value = "查询人员", type = OpsLogTypeEnum.SELECT)
    @GetMapping
    public BaseResponse<Page<HosPerson>> find(HosPerson hosPerson, QueryRequest queryRequest) {
        Page<HosPerson> result = this.hosPersonService.findHosPerson(hosPerson, queryRequest);
        return BaseResponse.success(result);
    }

    @ApiOperation(value = "更新人员")
    @ApiOperationSupport(order = 67)
    @OpsLog(value = "更新人员", type = OpsLogTypeEnum.UPDATE)
    @OperLog(title = "更新人员", content = "更新人员")
    @PutMapping
    public BaseResponse<HosPerson> update(@Valid HosPerson hosPersonVO) {
        setPhoto(hosPersonVO);
        this.hosPersonService.updateHosPerson(hosPersonVO);
        return BaseResponse.success();
    }

    @ApiOperation(value = "删除人员")
    @ApiOperationSupport(order = 67)
    @ApiImplicitParam(name = "personId", value = "人员PA_PersonID[多个以,分隔]", paramType = "path")
    @OpsLog(value = "删除人员", type = OpsLogTypeEnum.DELETE)
    @OperLog(title = "删除人员", content = "删除人员")
    @DeleteMapping("/{personId}")
    public BaseResponse<ErrorMsgVO> delete(@PathVariable @NotBlank(message = "不能为空") String personId) {
        ErrorMsgVO msgVO = this.hosPersonService.deleteHosPerson(personId);
        return BaseResponse.success(msgVO);
    }

    /*@ApiOperation(value = "导出人员")
    @ApiOperationSupport(order = 67)
    @OpsLog(value = "导出人员", type = OpsLogTypeEnum.DOWNLOAD)
    @OperLog(title = "导出人员", content = "导出人员")
    @GetMapping("/export")
    public void export(HosPerson hosPersonVO) {
        List<HosPerson> positions = this.hosPersonService.findHosPerson(hosPersonVO, new QueryRequest(1, Integer.MAX_VALUE)).getRecords();
        ExcelUtil<HosPerson> util = new ExcelUtil<>(HosPerson.class);
        util.exportExcel(HttpContextUtil.getResponse(), positions, "人员");
    }

    @ApiOperation(value = "导出人员模板")
    @ApiOperationSupport(order = 67)
    @OpsLog(value = "导出人员模板", type = OpsLogTypeEnum.DOWNLOAD)
    @Log(title = "导出人员模板", businessType = BusinessType.EXPORT)
    @GetMapping("/template")
    @ResponseBody
    public void hosPersonTemplate() {
        ExcelUtil<HosPerson> util = new ExcelUtil<>(HosPerson.class);
        util.importTemplateExcel(HttpContextUtil.getResponse(), "人员模板");
    }

    @ApiOperation(value = "导入人员")
    @ApiOperationSupport(order = 67)
    @OpsLog(value = "导入人员", type = OpsLogTypeEnum.UPLOAD)
    @Log(title = "导入人员", businessType = BusinessType.IMPORT)
    @PostMapping("/import")
    public BaseResponse<ErrorMsgVO> uploadHosPerson(MultipartFile file, boolean updateSupport) throws Exception {
        ExcelUtil<HosPerson> util = new ExcelUtil<>(HosPerson.class);
        List<HosPerson> personList = util.importExcel(file.getInputStream());
        ErrorMsgVO result = this.hosPersonService.importHosPerson(personList, updateSupport);
        return BaseResponse.success(result);
    }*/

    @ApiOperation(value = "上传人员照片")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "personId", value = "人员编号", paramType = "query"),
            @ApiImplicitParam(name = "photoFile", value = "文件", paramType = "query")
    })
    @ApiOperationSupport(order = 67, responses = @DynamicResponseParameters(properties = {
            @DynamicParameter(value = "imgUrl", name = "图片路径，添加人员时可作为query传入", example = ""),
    })
    )
    @OpsLog(value = "上传人员照片", type = OpsLogTypeEnum.UPLOAD)
    @OperLog(title = "上传人员照片", content = "上传人员照片")
    @PostMapping("/photo")
    public BaseResponse<String> uploadPhoto(MultipartFile file) throws Exception {
        if (!file.isEmpty()) {
            //上传文件至指定路径
            JSONObject jsonObject = new JSONObject();
            String imgUrl = FileUploadUtils.upload(DmpBaseConfig.getAvatarPath(), file);
            jsonObject.set("imgUrl", imgUrl);
            return BaseResponse.success(JSONUtil.toJsonPrettyStr(jsonObject));
        }
        return BaseResponse.error("上传图片异常，请联系管理员");
    }

    @ApiOperation(value = "获取人员照片")
    @ApiOperationSupport(order = 67)
    @OpsLog(value = "获取人员照片", type = OpsLogTypeEnum.UPLOAD)
    @OperLog(title = "获取人员照片", content = "获取人员照片")
    @GetMapping("/{personId}/photo")
    public void getPhoto(@PathVariable @NotBlank(message = "不能为空") String personId, HttpServletResponse response) throws Exception {
        List<HosPerson> list = this.hosPersonService.findHosPerson(HosPerson.builder().paPersonID(personId).build(), new QueryRequest()).getRecords();
        if (CollUtil.isEmpty(list)) {
            throw new DataException(StrUtil.format("【PA_PersonID = {}】不存在", personId));
        }
        try {
            //将图片转码后输出到页面上
            byte[] photo = Base64Decoder.decode(list.get(0).getPaPhoto());
            OutputStream out = response.getOutputStream();
            String extendName = FileUtils.getFileExtendName(photo);
            if (StringUtils.equalsIgnoreCase(ImgUtil.IMAGE_TYPE_JPG, extendName)) {
                response.setContentType(MediaType.IMAGE_JPEG_VALUE);
            }
            if (StringUtils.equalsIgnoreCase(ImgUtil.IMAGE_TYPE_PNG, extendName)) {
                response.setContentType(MediaType.IMAGE_PNG_VALUE);
            }
            IoUtil.write(out, true, photo);
        } catch (IOException e) {
            log.error("err in getPhoto. personId:{}", personId);
        }
    }

    @ApiOperation(value = "根据组织查询人员")
    @ApiOperationSupport(order = 67)
    @OpsLog(value = "根据组织查询人员", type = OpsLogTypeEnum.SELECT)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orgCode", value = "组织代码", paramType = "query")
    })
    @GetMapping("/org")
    public BaseResponse<Page<HosPerson>> findByOrg(String orgCode, QueryRequest queryRequest) {
        Page<HosPerson> result = this.hosPersonService.findHosPerson(orgCode, queryRequest);
        return BaseResponse.success(result);
    }

    /*@ApiOperation(value = "新增人员组织关联")
    @ApiOperationSupport(order = 67)
    @OpsLog(value = "新增人员组织关联", type = OpsLogTypeEnum.INSERT)
    @Log(title = "新增人员组织关联", businessType = BusinessType.INSERT)
    @PostMapping
    public R<HosPerson> saveHosOrgEmployee(@Valid HosOrgEmployee hosOrgEmployee) {
        this.hosOrgEmployeeService.save(hosOrgEmployee);
        return R.success();
    }


    @ApiOperation(value = "保存人员职务关联")
    @ApiOperationSupport(order = 67)
    @OpsLog(value = "保存人员职务关联", type = OpsLogTypeEnum.INSERT)
    @Log(title = "保存人员职务关联", businessType = BusinessType.INSERT)
    @PostMapping
    public R<HosPerson> saveHosEmpPostion(@Valid HosPerson hosPersonVO, String orgCode, String postCode, String... paPersonID) {
        //1、保存人员主体
        this.hosPersonService.saveHosPerson(hosPersonVO);
        //2、保存人员职务关联

        return R.success();
    }*/
}
